package com.nowcoder.community.quartz;

import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.service.impl.DiscussPostServiceImpl;
import com.nowcoder.community.service.impl.ElasticSearchServiceImpl;
import com.nowcoder.community.service.impl.LikeServiceImpl;
import com.nowcoder.community.util.CommunityConstant;
import com.nowcoder.community.util.RedisKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Date;

/**
 * @author cjh
 * @date 2023/2/11 - 16:02
 */
@Slf4j
public class PostScoreRefresfJob implements Job, CommunityConstant {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DiscussPostServiceImpl discussPostService;
    @Autowired
    private ElasticSearchServiceImpl elasticSearchService;
    @Autowired
    private LikeServiceImpl likeService;

    private static final Date epoch;

    static {
        try {
            epoch = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                    .parse("2014-08-01 00:00:00");
        } catch (ParseException e) {
            throw new RuntimeException("初始化牛科纪元失败",e);
        }
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String redisKey = RedisKeyUtil.getPostScoreKey();
        BoundSetOperations operations = redisTemplate.boundSetOps(redisKey);
        if (operations.size() == 0) {
            log.info("任务取消 没有需要刷新的帖子");
        }
        log.info("任务开始 正在刷新帖子分数"+operations.size());
        while (operations.size() > 0) {
            Object pop = operations.pop();
            log.info(pop.getClass().getName() );
//            int id = Integer.parseInt(pop.toString());
            this.refresh((Integer)pop);
        }
        log.info("任务结束 帖子分数 刷新完毕");
    }

    private void refresh(int postId) {
        DiscussPost post = discussPostService.getById(postId);
//        如果用postman对一个已经删除的帖子发送点赞like请求，
//        那么不就触发这个条件了吗，判断一下更严谨
//        因为这里  getbyid 是直接判断id 没有判断status
        if(post.getStatus() == 2){
            log.error("帖子已被删除");
            return;
        }

        if (post == null) {
            log.error("该帖子不存在：id"+postId);
            return;
        }
//        是否精华
        boolean wonderful = post.getStatus() == 1;
//        评论数量
        Integer commentCount = post.getCommentCount();
//        点赞数量
        long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, postId);

//        计算权重
        double w = (wonderful ? 75: 0)+commentCount*10+likeCount*2;
//        分数=帖子权重+距离天数
        double score = Math.log(Math.max(1,w)) +
                (post.getCreateTime().toInstant(ZoneOffset.of("+8")).toEpochMilli()-epoch.getTime())
                /(1000 * 3600*24);
//        更新帖子分数
        discussPostService.updateScore(postId,score);
//        同步搜索数据
        post.setScore(score);
        elasticSearchService.saveDiscussPost(post);
    }
}
